package exebuilder.controller;

import exebuilder.core.AppBuilder;
import exebuilder.core.Controllers;
import exebuilder.core.ViewLoader;
import exebuilder.data.AppConfig;
import exebuilder.data.Description;
import exebuilder.ui.MessageBox;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;

public class MainController implements Initializable {
 private static final Logger logger = LogManager.getLogger();
 public Label stepTitle;
 public Label stepInfo;
 public Button nextButton, backButton;
 public static int MAX_STEP = 4;
 public HBox stepButtons;
 Integer step = 0;

 AppConfig appConfig = AppConfig.getInstance();
 FirstController firstController;
 SecondController secondController;
 ThirdController thirdController;
 EndController endController;

 Parent firstView, secondView, thirdView, endView;


 @FXML
 BorderPane rootView;

 @FXML
 private void nextView() throws Exception {
  if (step == MAX_STEP) {
   CompletableFuture.runAsync(() -> {
    var appBuilder = new AppBuilder();
    appBuilder.build();
   });
  } else {
   try {
    saveData();
   } catch (Exception e) {
    logger.error(e);
    throw e;
   }
   step += 1;
   goView();
  }
 }

 @FXML
 private void backView() {
  if (step == 0) {
   return;
  }
  step -= 1;
  goView();
 }


 private void goView() {
  var buttons = stepButtons.getChildren();

  if (step == 0 && buttons.contains(backButton)) {
   stepButtons.getChildren().remove(backButton);
  }
  if (step > 0 && !buttons.contains(backButton)) {
   stepButtons.getChildren().add(0, backButton);
  }

  if (step == MAX_STEP && buttons.contains(nextButton)) {
   nextButton.setText("开 始");
  } else {
   if (!nextButton.getText().equals("下一步"))
    nextButton.setText("下一步");
  }

  if (step == 0) {
   stepTitle.setText(Description.STEP_0_TITLE);
   stepInfo.setText(Description.STEP_0_INFO);
   rootView.setCenter(null);
  }
  if (step == 1) {
   if (firstView == null) {
    firstView = ViewLoader.load("firstView");
   }
   stepTitle.setText(Description.STEP_1_TITLE);
   stepInfo.setText(Description.STEP_1_INFO);
   rootView.setCenter(firstView);
  }
  if (step == 2) {
   if (secondView == null) {
    secondView = ViewLoader.load("secondView");
   }
   stepTitle.setText(Description.STEP_2_TITLE);
   stepInfo.setText(Description.STEP_2_INFO);
   rootView.setCenter(secondView);
  }

  if (step == 3) {
   if (thirdView == null) {
    thirdView = ViewLoader.load("thirdView");
   }
   stepTitle.setText(Description.STEP_3_TITLE);
   stepInfo.setText(Description.STEP_3_INFO);
   rootView.setCenter(thirdView);
  }
  if (step == 4) {
   if (endView == null) {
    endView = ViewLoader.load("endView");
   }
   stepTitle.setText(Description.STEP_4_TITLE);
   stepInfo.setText(Description.STEP_4_INFO);
   rootView.setLeft(null);
   rootView.setCenter(endView);
   endController = (EndController) Controllers.get("end");
   endController.showBuildInfo();
  }
 }

 private void saveData() throws Exception {
  if (this.step == 1) {
   firstController = (FirstController) Controllers.get("first");
   var appName = firstController.appNameField.getText();
   var outputPath = firstController.outputPathField.getText();
   if (firstController.guiRadioButton.isSelected()) {
    appConfig.setAppType(0);
   } else if (firstController.consoleRadioButton.isSelected()) {
    appConfig.setAppType(1);
   } else {
    appConfig.setAppType(2);
   }
   if (!StringUtils.isBlank(appName)) {
    appConfig.setAppName(appName);
   }
   if (StringUtils.isBlank(outputPath)) {
    MessageBox.error("输出目录不能为空");
    throw new Exception("输出目录不能为空");
   } else {
    appConfig.setOutputPath(outputPath);
   }
  }

  if (this.step == 2) {
   secondController = (SecondController) Controllers.get("second");
   var jdkVersion = secondController.jdkVersionComboBox.getValue();
   var jdkPath = secondController.jdkPathField.getText();
   var sourcePath = secondController.sourcePathField.getText();
   var mainJarFile = secondController.mainJarFileField.getText();
   var mainClass = secondController.mainClassField.getText();
   var libPath = secondController.libPathField.getText();

   if (StringUtils.isBlank(jdkPath)) {
    MessageBox.error("JDK目录不能为空");
    throw new Exception("JDK目录不能为空");
   }
   if (StringUtils.isBlank(sourcePath)) {
    MessageBox.error("源文件目录不能为空");
    throw new Exception("源文件目录不能为空");
   }
   if (sourcePath.equals(appConfig.getOutputPath())) {
    MessageBox.error("输出目录不能与源文件目录相同");
    throw new Exception("输出目录不能与源文件目录相同");
   }
   if (StringUtils.isBlank(mainJarFile)) {
    MessageBox.error("mainJar文件不能为空");
    throw new Exception("mainJar文件不能为空");
   }
   if (StringUtils.isBlank(mainClass)) {
    MessageBox.error("MainClass不能为空");
    throw new Exception("MainClass不能为空");
   }
   appConfig.setJdkVersion(jdkVersion);
   appConfig.setJdkPath(jdkPath);
   appConfig.setSourcePath(sourcePath);
   appConfig.setMainJarFile(mainJarFile);
   appConfig.setMainClass(mainClass);
   if (!StringUtils.isBlank(libPath)) {
    appConfig.setLibPath(libPath);
   }
  }

  if (this.step == 3) {
   thirdController = (ThirdController) Controllers.get("third");
   var iconPath = thirdController.iconPathField.getText();
   var version = thirdController.versionField.getText();
   var copyright = thirdController.copyrightField.getText();
   if (!StringUtils.isBlank(iconPath)) {
    appConfig.setIconPath(iconPath);
   }
   if (!StringUtils.isBlank(version)) {
    appConfig.setVersion(version);
   }
   if (!StringUtils.isBlank(copyright)) {
    appConfig.setCopyright(copyright);
   }
  }

  logger.debug(appConfig);
 }


 @Override
 public void initialize(URL url, ResourceBundle resourceBundle) {
  Controllers.add("main", this);
  stepTitle.setText(Description.STEP_0_TITLE);
  stepInfo.setText(Description.STEP_0_INFO);
  stepButtons.getChildren().remove(backButton);
 }
}
